package com.gupaoedu.curator;


import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;


/**
 * addListenerWithNode （） 是监听当前节点、
 *
 * addListenerWithChild（） 是监听子节点。。
 *
 * 这个demo很重要
 *
 */
public class WatchDemo {

    private static String CONNECTION_STR="192.168.13.102:2181,192.168.13.103:2181,192.168.13.104:2181";

    public static void main(String[] args) throws Exception {
        //PathChildCache  --针对于子节点的创建、删除和更新 触发事件
        //NodeCache  针对当前节点的变化触发事件
        //TreeCache  综合事件

        CuratorFramework curatorFramework = CuratorFrameworkFactory.builder().
                connectString(CONNECTION_STR).sessionTimeoutMs(5000).
                retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
        curatorFramework.start();
        addListenerWithNode(curatorFramework);
//        addListenerWithChild(curatorFramework);

        //阻塞在那里，防止main线程结束
        System.in.read();

    }

    //对 创建、修改、删除 做监听，这恰恰符合注册中心的需求。。 所以可以拿来做注册中心

    private static void addListenerWithNode(CuratorFramework curatorFramework) throws Exception {
        //这句话的作用：针对于当前会话下的/watch这个节点 来设置事件。（第二个参数是数据压缩，先设为false）
        NodeCache nodeCache=new NodeCache(curatorFramework,"/watch",false);
        //设置好了某个节点的事件之后，再设置一个监听
        NodeCacheListener nodeCacheListener= () -> {
            System.out.println("receive Node Changed");
            //当节点发生变化之后，
            System.out.println(nodeCache.getCurrentData().getPath()+"---"+new String(nodeCache.getCurrentData().getData()));
        };
        //事件上加上监听
        nodeCache.getListenable().addListener(nodeCacheListener);
        nodeCache.start();
    }

    //只会 监听watch下子节点的变化。。
    //这就使得可以做这个事：实现服务注册中心的时候，可以针对服务做动态感知
    private static void addListenerWithChild(CuratorFramework curatorFramework) throws Exception {
        PathChildrenCache nodeCache=new PathChildrenCache(curatorFramework,"/watch",true);
        PathChildrenCacheListener nodeCacheListener= (curatorFramework1,pathChildrenCacheEvent) -> {
            System.out.println(pathChildrenCacheEvent.getType()+"->"+new String(pathChildrenCacheEvent.getData().getData()));
        };
        nodeCache.getListenable().addListener(nodeCacheListener);
        //这三个模式，后面会讲到
        nodeCache.start(PathChildrenCache.StartMode.NORMAL);
    }

}
